<template>
  <div class="page">
    <nav-bar
      title="购物金记录"
      back-text="返回商城"
      @on-back="handleBack"
      @on-refresh="handleRefresh"
    />
    <div class="record">
      <div class="record-item" v-for="(record, idx) in recordList" :key="idx">
        <record-card :record="record" />
      </div>
      <empty-card v-if="recordData.list.length === 0" :custom-style="'margin-top: 90px'" />
      <no-data v-if="recordData.list.length && recordData.loadAll" />
    </div>
    <div ref="observerRef" class="observer"></div>
  </div>
</template>
<script setup lang="ts">
import RecordCard from '@/components/RecordCard.vue'
import EmptyCard from '@/components/EmptyCard.vue'
import NoData from '@/components/NoData.vue'
import NavBar from '@/components/NavBar.vue'
import { AppService } from '@/logics/services/app'
import { MallService } from '@/logics/services/mall'
import type { PageListData } from '@/types'
import type { APIGetRecordReqData } from '@/types/api/mall'
import type { OrderRecordItem, RecordItem } from '@/types/mall'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { MallAdapter } from '@/logics/adapters/mall'
import { browserBack, simpleCopy } from '@/utils/utils'
let observer: IntersectionObserver | null = null
const emptyData = { page: 1, size: 10, loading: false, loadAll: false, list: [] }
const mallService = new MallService()
const appService = new AppService()
const route = useRoute()
const mobile = ref('')
const observerRef = ref<HTMLElement | null>(null)
const recordData = ref<PageListData<OrderRecordItem>>({
  page: 1,
  size: 10,
  loading: false,
  loadAll: false,
  list: [],
})
const recordList = computed<RecordItem[]>(() => {
  return MallAdapter.fromOrderRecordsToList(recordData.value.list || [])
})
const queryRecord = async () => {
  try {
    const { page, size, loading, loadAll } = recordData.value
    if (loading || loadAll) {
      return
    }
    recordData.value.loading = true
    const params: APIGetRecordReqData = {
      page,
      page_size: size,
      mobile: mobile.value,
    }
    const list = await mallService.getRecordList(params)
    recordData.value.loading = false
    recordData.value.loadAll = list.length < size
    recordData.value.list = page === 1 ? list : [...recordData.value.list, ...list]
  } catch (err: unknown) {
    recordData.value.loading = false
    console.error('获取购物金记录列表失败', err)
  }
}
const queryMobile = async () => {
  if (route.query.mobile) {
    mobile.value = route.query.mobile as string
  } else {
    const user = await appService.getAPPUserInfo()
    mobile.value = user.mobile
  }
}
const listenObserver = () => {
  offObserver()
  observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      recordData.value.page++
      queryRecord()
    }
  })
  observer.observe(observerRef.value as HTMLElement)
}
const offObserver = () => {
  if (observer) {
    observer.disconnect()
  }
}
const handleBack = () => {
  browserBack()
}
const handleReset = () => {
  recordData.value = simpleCopy(emptyData)
}
const handleRefresh = () => {
  document.documentElement.scrollTop = 0
  document.body.scrollTop = 0
  handleReset()
  setUp()
}
const setUp = async () => {
  listenObserver()
  await queryMobile()
  queryRecord()
}
const setDown = () => {
  offObserver()
}
onMounted(() => {
  setUp()
})
onBeforeUnmount(() => {
  setDown()
})
</script>
<style scoped lang="scss">
.page {
  background: #f7f7f7;
  min-height: 100vh;
}
.record {
  padding: 12px;
  box-sizing: border-box;
  .record-item {
    background: #fff;
  }
}
</style>
